using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

namespace Scheduling.Services.Weathers
{
    /// <summary>
    /// 天气服务实现
    /// </summary>
    public class WeatherService : IWeatherService
    {
        private readonly HttpClient _httpClient;
        private readonly string _apiKey;

        public WeatherService(HttpClient httpClient)
        {
            _httpClient = httpClient;
            _apiKey = "eb702178680854c0804d16a24cfc5071"; // 高德开放平台API Key
        }

        /// <summary>
        /// 根据城市编码获取天气信息
        /// </summary>
        public async Task<string> GetWeatherByCityCodeAsync(string cityCode, string extensions = "base")
        {
            if (string.IsNullOrWhiteSpace(cityCode))
            {
                throw new ArgumentException("城市编码不能为空", nameof(cityCode));
            }

            var url = $"https://restapi.amap.com/v3/weather/weatherInfo?key={_apiKey}&city={cityCode}&extensions={extensions}";
            
            try
            {
                var response = await _httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
            catch (HttpRequestException ex)
            {
                throw new Exception($"获取天气信息失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 根据经纬度获取天气信息
        /// </summary>
        public async Task<string> GetWeatherByLocationAsync(double longitude, double latitude, string extensions = "base")
        {
            // 先通过经纬度获取城市编码
            var cityCode = await GetCityCodeByLocationAsync(longitude, latitude);
            
            // 再根据城市编码获取天气信息
            return await GetWeatherByCityCodeAsync(cityCode, extensions);
        }

        /// <summary>
        /// 根据经纬度获取城市编码
        /// </summary>
        public async Task<string> GetCityCodeByLocationAsync(double longitude, double latitude)
        {
            var url = $"https://restapi.amap.com/v3/geocode/regeo?key={_apiKey}&location={longitude},{latitude}&extensions=base";
            
            try
            {
                var response = await _httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();
                var jsonResponse = await response.Content.ReadAsStringAsync();
                
                return ParseCityCodeFromJson(jsonResponse);
            }
            catch (HttpRequestException ex)
            {
                throw new Exception($"获取城市编码失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 从JSON响应中解析城市编码
        /// </summary>
        private string ParseCityCodeFromJson(string jsonResponse)
        {
            try
            {
                using var document = JsonDocument.Parse(jsonResponse);
                var root = document.RootElement;

                // 检查API调用状态
                if (root.TryGetProperty("status", out var statusElement))
                {
                    var status = statusElement.ValueKind == JsonValueKind.String ? 
                        statusElement.GetString() : 
                        statusElement.GetRawText();
                    
                    if (status != "1")
                    {
                        var info = "未知错误";
                        if (root.TryGetProperty("info", out var infoElement))
                        {
                            info = infoElement.ValueKind == JsonValueKind.String ? 
                                infoElement.GetString() : 
                                infoElement.GetRawText();
                        }
                        throw new Exception($"高德逆地理API调用失败: {info}");
                    }
                }

                // 解析城市编码
                if (root.TryGetProperty("regeocode", out var regeocodeElement) &&
                    regeocodeElement.TryGetProperty("addressComponent", out var addressComponentElement) &&
                    addressComponentElement.TryGetProperty("adcode", out var adcodeElement))
                {
                    return ExtractAdcode(adcodeElement);
                }

                throw new Exception("逆地理结果中未找到城市编码字段");
            }
            catch (JsonException ex)
            {
                throw new Exception($"解析逆地理JSON结果失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 提取城市编码，处理字符串和数组两种情况
        /// </summary>
        private string ExtractAdcode(JsonElement adcodeElement)
        {
            if (adcodeElement.ValueKind == JsonValueKind.String)
            {
                var adcode = adcodeElement.GetString();
                if (string.IsNullOrWhiteSpace(adcode))
                {
                    throw new Exception("逆地理结果中的城市编码为空字符串");
                }
                return adcode;
            }
            else if (adcodeElement.ValueKind == JsonValueKind.Array)
            {
                if (adcodeElement.GetArrayLength() == 0)
                {
                    throw new Exception("逆地理结果中的城市编码为空数组，无法确定具体位置");
                }
                
                var firstElement = adcodeElement.EnumerateArray().First();
                if (firstElement.ValueKind == JsonValueKind.String)
                {
                    var adcode = firstElement.GetString();
                    if (string.IsNullOrWhiteSpace(adcode))
                    {
                        throw new Exception("逆地理结果中的城市编码数组第一个元素为空");
                    }
                    return adcode;
                }
                else
                {
                    throw new Exception($"城市编码数组中的元素类型错误，期望字符串，实际为: {firstElement.ValueKind}");
                }
            }
            else
            {
                throw new Exception($"城市编码字段类型错误，期望字符串或数组，实际为: {adcodeElement.ValueKind}");
            }
        }
    }
}

